home *** CD-ROM | disk | FTP | other *** search
- /* Unca Fenster
- *
- * by Timothy Knox & Ed Tecot
- *
- * Written at MacHack 1993
- *
- * Unca Fenster saves the state of all of your open windows in a file called
- * "Fenster Data". You can rename the file and put it anywhere. Double-Click
- * on an Unca Fenster file to open all of the windows and restore their state.
- *
- * Well... not really. The intent is to do all that, but for now, all that
- * is restored is the back-to-front ordering of the windows. The rest is left
- * as an exercise for the hacker. In addition, aliases that don't resolve are
- * ignored. If you want something better, do it youself and submit it next year!
- */
-
- #include "Layers.h"
- #include "FinderToFSSpec.h"
- #include <Aliases.h>
- #include <AppleEvents.h>
-
- #define rFensCreat 'UNCA'
- #define rFensType 'FNST'
-
- // Special Undocumented Routines for System Mode
- pascal OSErr TurnSystemModeOn(void) = {0x2F3C, 0x0040, 0x0000, 0xA88F};
- pascal OSErr TurnSystemModeOff(void) = {0x2F3C, 0x0041, 0x0000, 0xA88F};
-
- void SendOpenDocToFinder(FSSpec *theCFS, long tId);
-
- typedef struct fWinAlias {
- Rect fRect;
- AliasRecord fAlias;
- } fWinAlias, *fWinAliasP, **fWinAliasH;
-
- typedef struct FinderWRefCon {
- void *dontKnow;
- void *dontKnowEither;
- FinderHandle theFH;
- } FinderWRefCon;
-
- void CreateFenster(void);
- void OpenFenster(AppFile *theFile);
-
- main()
- {
- short message, count;
-
- MaxApplZone(); /* expand the heap so code segments load at the top */
- InitGraf((Ptr) &qd.thePort);
-
- /* We can't use the event manager, so get the files the old fashioned way */
- CountAppFiles(&message, &count);
- if (count) {
- short index;
- AppFile theFile;
- for (index = 1; index <= count; index++) {
- GetAppFiles(index, &theFile);
- OpenFenster(&theFile);
- ClrAppFiles(index);
- }
- } else
- CreateFenster();
- ExitToShell();
- }
-
- /* Go scan the Finder for the appropriate stuff and store it in a file. */
- void CreateFenster()
- {
- FSSpec theSpec;
- AliasHandle theAliasH;
- Handle rectH;
- long **fWinCount = (long **) NewHandle(sizeof(long));
- int ref;
- long c = 0;
- OSErr err;
- WindowPeek aFinderWindow = (WindowPeek) GetFirstLayerWindow((LayerPtr) GetFirstLayerWindow(GetFirstLayer()));
-
- HGetVol(theSpec.name, &theSpec.vRefNum, &theSpec.parID);
- BlockMove("\pFenster Data", theSpec.name, 13);
- FSpCreateResFile(&theSpec, rFensCreat, rFensType, 0);
- err = ResError();
- if (!((err == noErr) || (err == dupFNErr)))
- return;
- ref = FSpOpenResFile(&theSpec, fsRdWrPerm);
- if (ref == -1)
- return;
-
- /* Find all of the windows in the frontmost app, which should be the Finder.
- * Skip the last window, because that's the desktop.
- */
- while (aFinderWindow && aFinderWindow->nextWindow) {
- FinderHandleToFSSpec(((* (FinderWRefCon **) GetWRefCon((WindowPtr) aFinderWindow)))->theFH, &theSpec);
- err = NewAlias(nil, &theSpec, &theAliasH);
- if ((err != noErr) || (theAliasH == nil)) {
- return;
- }
- rectH = NewHandle(sizeof(Rect));
- BlockMove(&aFinderWindow->port.portRect, *rectH, sizeof(Rect));
- AddResource(rectH, 'RECT', ++c, "\p");
- AddResource((Handle) theAliasH, 'alis', c, "\p");
- aFinderWindow = aFinderWindow->nextWindow;
- }
- **fWinCount = c;
- AddResource((Handle) fWinCount, 'CNT!', 0, "\p");
- CloseResFile(ref);
- }
-
- /* Read the fenster file and open the windows and move them to the proper place */
- void OpenFenster(AppFile *theFile)
- {
- FSSpec theSpec;
- AliasHandle theAliasH;
- Handle rectH;
- long **fWinCount;
- Boolean wasChanged;
- int ref;
- long c;
- OSErr err;
-
- SetVol(nil, theFile->vRefNum);
- ref = OpenResFile (theFile->fName);
- if (ref == -1)
- return;
-
- fWinCount = (long **) GetResource('CNT!', 0);
- err = ResError();
- if (err != noErr)
- return;
-
- for (c = **fWinCount; c > 0; c--) {
- theAliasH = (AliasHandle) GetResource('alis', c);
- err = ResolveAlias(nil, theAliasH, &theSpec, &wasChanged);
- ReleaseResource((Handle) theAliasH);
- if (err != noErr)
- break;
- rectH = GetResource('RECT', c);
- SendOpenDocToFinder(&theSpec, c);
- }
- }
-
- #define kAEOpenSelection 'sope'
- #define kAEFinderEvents 'FNDR'
- #define keySelection 'fsel'
- #define keyDirectObject '----'
-
- /* send an open msg to Finder for vol,dir,name */
- void SendOpenDocToFinder(FSSpec *theCFS, long tId)
- {
- AliasHandle theAlias;
- AppleEvent theMessage,theReply;
- AEAddressDesc theAddress;
- AEDesc theSelAliasList,theSelAliasElement,theParAliasElement;
- int i;
- OSType fndrSig = 'MACS';
-
- TurnSystemModeOn();
-
- AECreateDesc(typeApplSignature,(Ptr)&fndrSig,sizeof(OSType),&theAddress);
-
- /* Create an AppleEvent message */
- AECreateAppleEvent(kAEFinderEvents,kAEOpenSelection,&theAddress,
- kAutoGenerateReturnID,tId,&theMessage);
-
- /* Create an alias to the parent folder and put it in the msg. */
- NewAlias(0L,theCFS,&theAlias);
-
- /* create an element */
- HLock((Handle) theAlias);
- AECreateDesc(typeAlias,(Ptr)*theAlias,(*theAlias)->aliasSize,&theParAliasElement);
-
- /* now put the element into the message */
- AEPutParamDesc(&theMessage, keyDirectObject,&theParAliasElement);
- DisposHandle((Handle) theAlias);
-
- /* Create a list (the key selection of the message), store the alias in it, and
- put the list in the msg. */
- AECreateList(0L,0,FALSE,&theSelAliasList);
-
- NewAlias(0L,theCFS,&theAlias);
-
- // create the alias descriptor
- HLock((Handle) theAlias);
- AECreateDesc(typeAlias,(Ptr)*theAlias,(*theAlias)->aliasSize,&theSelAliasElement);
-
- /* put the element into the list */
- AEPutDesc(&theSelAliasList,0,&theSelAliasElement);
- DisposHandle((Handle) theAlias);
-
- /* now put the list into the message */
- AEPutParamDesc(&theMessage, keySelection,&theSelAliasList);
-
- /* Send it off. */
- AESend(&theMessage,0L, kAENoReply, kAENormalPriority,1000,0L,0L);
-
- AEDisposeDesc(&theAddress);
- AEDisposeDesc(&theMessage);
- AEDisposeDesc(&theSelAliasElement);
- AEDisposeDesc(&theSelAliasList);
- AEDisposeDesc(&theParAliasElement);
-
- TurnSystemModeOff();
- }
-